package com.roncoo.example.controller;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;

@Controller
public class StreamingResponseBodyController {

  private static Logger logger = LoggerFactory.getLogger(StreamingResponseBodyController.class);

  @RequestMapping("/sync/test1")
  public ResponseEntity<StreamingResponseBody> handleRequest() {

    StreamingResponseBody responseBody = new StreamingResponseBody() {
      @Override
      public void writeTo(OutputStream out) throws IOException {
        for (int i = 0; i < 1000; i++) {
          out.write((Integer.toString(i) + " - ")
              .getBytes());
          out.flush();
          try {
            Thread.sleep(5);
            logger.info("sleep...." + i);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }

        }
        logger.info("finish....");
      }
    };
    logger.info("done....");
    return new ResponseEntity(responseBody, HttpStatus.OK);
  }

  @RequestMapping("/sync/test2")
  public StreamingResponseBody handleRequest(HttpServletRequest r) {
    System.out.println("asyncSupported: " + r.isAsyncSupported());
    System.out.println(Thread.currentThread().getName());

    return new StreamingResponseBody() {
      @Override
      public void writeTo(OutputStream outputStream) throws IOException {
        System.out.println(Thread.currentThread().getName());
        outputStream.write("from test request".getBytes());
      }
    };
  }

  @RequestMapping("/sync/test3")
  public StreamingResponseBody handleRequest2() {
    return outputStream -> {
      Map<String, BigInteger> map = new HashMap<>();
      map.put("one", BigInteger.ONE);
      map.put("ten", BigInteger.TEN);
      try (ObjectOutputStream oos = new ObjectOutputStream(outputStream)) {
        oos.writeObject(map);
      }
    };
  }
}
